﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Data.SqlClient;

namespace Open.Data.Persistence.SqlServer
{
    //Binds the current values of a sql data reader to an item of type T
    public sealed class SqlDataBinder<T>: DataBinder<T>
    where T : class, IPersistable, new()
    {
        public SqlDataBinder(IQuery query): base(query)
        {

        }
        public override bool Read()
        {
            if (DataAdapter == null) throw new DataBinderException("Set the DataAdapter property before performing a read operation.");
            return DataAdapter.Read();
        }

        //Bind to the current row of the reader.
        public override void Bind()
        {
            Formatter formatter = Formatter as SqlFormatter;
            
            //Create an item if required
            if (Item == null)
            {
                CreateItem();

                if (Item is IConcurrency)
                {
                    IConcurrency concurrency = (IConcurrency) Item;
                    concurrency.SetConcurrency(formatter.Command.Context.CreateConcurrency());
                    
                }
            }

            //Set the concurrency
            if (Item is IConcurrency)
            {
                IConcurrency concurrency = (IConcurrency)Item;
                formatter.Concurrency = concurrency.GetConcurrency();
            }
            
            formatter.Decode(Item, typeof(T));
        }

        //Return a list of unique objects when there is no adapter
        //Otherwise forces the adapter to create an object graph for the query
        public override List<T> ToList()
        {
            if (DataAdapter == null) throw new DataBinderException("List could not be created because the DataAdapter was not set.");
            return DataAdapter.CreateList<T>(this);
        }
    }
}
